package xyz.xtt.admin.listener;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.admin.constants.AssetHandleEnum;
import xyz.xtt.admin.constants.OrderTypeEnum;
import xyz.xtt.admin.entity.TblActivity;
import xyz.xtt.admin.entity.TblActivityLog;
import xyz.xtt.admin.entity.TblUser;
import xyz.xtt.admin.service.IActivityLogService;
import xyz.xtt.admin.service.IUserService;
import xyz.xtt.asset.client.AssetClient;
import xyz.xtt.asset.client.request.TransferFromRequest;
import xyz.xtt.asset.client.response.TransferFromResponse;
import xyz.xtt.common.response.ApiResult;

/**
 * @author Jim kwok
 * @since 2025/2/28
 */
@Slf4j
@Component
public class AssetHandleListener {
	@Autowired
	AssetClient assetClient;

	@Autowired
	IUserService userService;

	@Autowired
	IActivityLogService activityLogService;

	/**
	 * 涉及跨服务调用划转资产，暂时不用多线程处理
	 */
	@Async("FixThreadEventExecutor")
	@EventListener
	void dropAsset(AssetHandleEvent<TblActivityLog, TblActivity> handleEvent) {
		String action = handleEvent.getAction();
		List<TblActivityLog> list = handleEvent.getList();
		TblActivity activity = handleEvent.getObj();
		// 参数检查
		Assert.notNull(action);
		Assert.isTrue(AssetHandleEnum.checkMethod(action));
		Assert.notNull(list);
		Assert.isTrue(!list.isEmpty());
		// 检查事件标识【空投、回收】
		if (action.equals(AssetHandleEnum.DROP_ASSET.method())) {
			drop(list, activity.getOwnerId(), activity.getGoodsId());
		}
		if (action.equals(AssetHandleEnum.REUSE_ASSET.method())) {
			reuse(list);
		}
		log.info("批量资产处理完成：{}条", list.size());
	}

	/**
	 * 开始空投
	 */
	void drop(List<TblActivityLog> list, Long from, Long goodsId) {
		Integer count = 0;
		for (TblActivityLog o : list) {
			// 校验用户信息
			TblUser u = userService.getUserByPhone(o.getUserPhone());
			if (Objects.nonNull(u)) {
				o.setUserId(u.getAppUserId());
				o.setUserName(u.getNickname());
				ApiResult<TransferFromResponse> result = getTransferFromResponseApiResult(from, goodsId, o);
				o.setStatus(1);
				if (!result.isOk()) {
					o.setStatus(2);
					log.error("[transferFrom] 资产发放失败, phone is " + o.getUserPhone());
				}
			} else {
				o.setStatus(5);
			}
			count += activityLogService.updateOne(o);
			try {
				TimeUnit.MILLISECONDS.sleep(50);
			} catch (InterruptedException e) {
				log.info("资产发放线程异常，{}", e.getMessage());
			}
		}
		log.info("资产发放完成：{}条", count);
	}

	@NotNull
	private ApiResult<TransferFromResponse> getTransferFromResponseApiResult(Long from, Long goodsId, TblActivityLog o) {
		TransferFromRequest transfer = TransferFromRequest
				.builder()
				.amount(o.getAmount())
				.from(from)
				.to(o.getUserId())
				.bizId(String.valueOf(goodsId))// 资产goodsID
				.orderNo(IdUtil.getSnowflake().nextIdStr())
				.orderType(OrderTypeEnum.ACTIVITY.name())
				.build();
		ApiResult<TransferFromResponse> result = assetClient.transferFrom(String.valueOf(o.getUserId()), transfer);
		log.info("remote api：/api/asset/nft/transferFrom :{},{},{}", result.getCode(), result.getMsg(), result.getData());
		return result;
	}

	/**
	 * 开始回收
	 */
	void reuse(List<TblActivityLog> list) {
		// 流程待定；
	}

}
